'Monitoring application.'
# running a local server to prove monitord is up
import server, protocol.node
# data acquisition
import statistics, watcher
# communication with master server
import client, protocol.master
# self-configuration
import neighbours
# system modules
import time, threading
# config
import conf

# how often to check for changes, in seconds
POLLING_INTERVAL = conf.POLLING_INTERVAL 
MASTER_ADDR = conf.MASTER_ADDR

def main():
    # start local server to respond to pings and whatnot
    thrd = threading.Thread(target=server.loop, 
                            args=(protocol.node.handler,))
    thrd.daemon = True # to ensure program exits even if thrd still runs
    #thrd.start()
    # TODO: REMOVE THIS ONCE YOU CAN TEST /w REMOTE SERVER!

    while 1:
        # look for things the server might want to know
        local_changes = statistics.gather()
        print 'Local changes:',local_changes
        node_changes = watcher.gather()
        print 'Node changes:',node_changes

        # and send them to the server
        try:
            s = client.connect(MASTER_ADDR)
            # 1: data push
            request = protocol.master.push_request(local_changes, node_changes)
            response = protocol.master.push_response(client.ask(s, request))
            print 'Data pushed to server.'
            # 2: node request
            print 'Node timestamps, server:',response,'mine:',neighbours.stamp
            if response!=neighbours.stamp:
                # request update!
                request = protocol.master.nodes_request()
                stamp,nodes = protocol.master.nodes_response(
                                                    client.ask(s, request))
                print 'Received',len(nodes),' new nodes with stamp:',stamp
                neighbours.set(stamp,nodes)
            client.close(s)
        except:
            import traceback
            traceback.print_exc()
            print 'Failed to connect to server. Aborting communication.'
        
        # then wait, to not waste resourses
        print 'Sleeping...'
        try: 
            time.sleep(POLLING_INTERVAL)
        except KeyboardInterrupt:
            print 'Exiting.'
            return 0
